package org.wak.action.modern
{
	import org.wak.action.ActionsFactory;
	import org.wak.action.IActionController;
	import org.wak.action.actions.AdventureActions;
	import org.wak.action.actions.BaseAction;
	import org.wak.character.AdventureCharacter;
	import org.wak.character.display.AbstractCharacterDisplay;
	import org.wak.gui.IAdventureGui;
	import org.wak.gui.events.GuiEvent;
	import org.wak.gui.modern.ModernGui;
	import org.wak.main.AdventureMaster;
	import org.wak.main.PuzzleControllerBase;
	import org.wak.scene.ActionSpot;
	import org.wak.scene.GateSpot;
	import org.wak.scene.SceneItem;
	import org.wak.scene.events.SceneEvent;
	import org.wak.utils.IIterator;

	/**
	 * Action controller for the modern adventure style 
	 * 
	 */	
	public class ActionControllerModern implements IActionController
	{
		/**
		 * Character the current player's character.		 
		 */		
		protected var mPlayerChar:AdventureCharacter = null ; 
		
		/**
		 * Local reference to the mdoern Gui.		 
		 */	
		protected var mModernGui:ModernGui = null ;
		
		/**
		 * The current active action. 
		 */		
		protected var mActiveAction:BaseAction = null ;
		
		/**
		 * Constructor. 
		 * 
		 */		
		public function ActionControllerModern()
		{
			mPlayerChar = AdventureMaster.CharactersMngr.GetCharacter( AdventureMaster.defaultPlayerCharacterId );
		}

		public function Initialize():void
		{
			var fAdventureGui:IAdventureGui = AdventureMaster.GuiMngr.adventureGui ;
			mModernGui = fAdventureGui as ModernGui ;
			
			if(ModernGui == null)
			{
				throw new Error("ActionControllerModern. Can't Initialize null Modern gui");
			}
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
		}
		
		public function OnSceneItemClick(event:SceneEvent):void
		{
			//trace("OnSceneItemClick:"+ event.interactable.interactableId );
			
			// if the active action is ready, this ends here
			if(mActiveAction.isReady )
				return ;
				
			mActiveAction.AddParameter(event.interactable);
			
			if( mActiveAction.isReady )
			{
				var fActionHandler:Function = null ;
				var fMethodFound:Boolean = mActiveAction.CanExecute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
				// If the method can execute
				mWalkCompleteBehaviour = event.interactable.interactionBehaviour ;
				if( fMethodFound )
				{
					//trace("method found");
					fActionHandler = OnActionWalkComplete ;
				}
				else
				{
					//trace("NO method found");
					fActionHandler = OnNoActionWalkComplete ;
				}
				// if the intearactable is no the player
				if( event.interactable.interactableId != mPlayerChar.characterDisplay.interactableId)
				{
					// walk to the interaction point
					mPlayerChar.MoveTo( event.interactable.interactionPointX, event.interactable.interactionPointY,fActionHandler);
				}
				else 
				{
					// directly call the handler.
					fActionHandler();
				}
					
			}
		}
		
		private var mWalkCompleteBehaviour:String = "" ;
		
		private function OnNoActionWalkComplete():void
		{
			mPlayerChar.characterDisplay.SetAnimBehaviour(mWalkCompleteBehaviour);
			mPlayerChar.Say(mActiveAction.GetNoActionText());
			if(mActiveAction.GetId() == AdventureActions.ActionIdUse)
				mModernGui.ReleaseItem() ;
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
		}
		
		private function OnActionWalkComplete():void
		{
			mPlayerChar.characterDisplay.SetAnimBehaviour(mWalkCompleteBehaviour);
			mActiveAction.Execute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
		}
		
		public function OnSceneItemMouseOver(event:SceneEvent):void
		{
			
			var fFeedbackText:String = "" ;
			if( !mModernGui.mouseInfoDescription )
			{
				fFeedbackText = event.interactable.interactionName ;
			}
			else
			{
				fFeedbackText = event.interactable.interactionName + "\n";
				fFeedbackText += event.interactable.description ;	
			}
			mModernGui.SetMouseInfoText( fFeedbackText );
			
			mModernGui.SetInfoBoxText( event.interactable.interactionName + "\n" + event.interactable.description );
			
			if( (event.interactable is SceneItem) || (event.interactable is ActionSpot) )
			{
				mModernGui.ChangeMouseCursorTo( ModernGui.ItemMouseCursor );
				return ;
			}
			else if (event.interactable is AbstractCharacterDisplay)
			{
				if(event.interactable != mPlayerChar.characterDisplay )
				{
					mModernGui.ChangeMouseCursorTo( ModernGui.CharMouseCursor );
				}
				else
				{
					mModernGui.ChangeMouseCursorTo( ModernGui.ItemMouseCursor );
				}
				
				return ;
			}
			else if( event.interactable is GateSpot )
			{
				mModernGui.ChangeMouseCursorTo( ModernGui.ExitMouseCursor );
				return ;
			}
			
			mModernGui.ChangeMouseCursorTo( ModernGui.NormalMouseCursor );
			
		}
		
		public function OnSceneItemMouseOut(event:SceneEvent):void
		{
			mModernGui.ChangeMouseCursorTo( ModernGui.NormalMouseCursor);
			mModernGui.SetMouseInfoText("");
			mModernGui.SetInfoBoxText(" ");
		}
		
		public function OnSceneSpaceClick(event:SceneEvent):void
		{
			if(	mActiveAction.isReady )
				mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
			
			mPlayerChar.MoveTo( event.sceneMouseX,event.sceneMouseY);
		}
		
		public function OnEnterScene(event:SceneEvent):void
		{
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
			mModernGui.ChangeMouseCursorTo( ModernGui.NormalMouseCursor ); 
			mModernGui.SetMouseInfoText("");
			mModernGui.SetInfoBoxText(" ");
			
			var fMethodName:String = "EnterScene"+event.sceneId ;
			
			var fPIt:IIterator = AdventureMaster.ActionsMngr.GetPuzzleControllers();
			
			
			var fMethodFound:Boolean = false ;
			var fPuz:PuzzleControllerBase = null ;
			while( fPIt.hasNext() )
			{
				fPuz = fPIt.next() as PuzzleControllerBase ;
				fMethodFound = fPuz.hasOwnProperty(fMethodName);
				if(fMethodFound)
				{
					fPuz[fMethodName](event.sceneId) ;
				}
			}
		}
		
		public function OnExitScene(event:SceneEvent):void
		{
			
			var fMethodName:String = "ExitScene"+event.sceneId ;
			
			var fPIt:IIterator = AdventureMaster.ActionsMngr.GetPuzzleControllers();
			
			
			var fMethodFound:Boolean = false ;
			var fPuz:PuzzleControllerBase = null ;
			while( fPIt.hasNext() )
			{
				fPuz = fPIt.next() as PuzzleControllerBase ;
				fMethodFound = fPuz.hasOwnProperty(fMethodName);
				if(fMethodFound)
				{
					fPuz[fMethodName](event.sceneId) ;
				}
			}
		}
		
		public function OnActionSelected(event:GuiEvent):void
		{
		}
		
		public function OnInventoryItemSelected(event:GuiEvent):void
		{
			//trace("OnInventoryItemSelected");
			
			var fMethodFound:Boolean = false ;
			if( mActiveAction.GetId() != AdventureActions.ActionIdUse)
			{
				mActiveAction = ActionsFactory.CreateAction(AdventureActions.ActionIdUse);
				mActiveAction.AddParameter(event.inventoryItem);
				mModernGui.GrabItem( event.inventoryItem.itemIconDisplay);
				
				// if it is unitary use.
				if(mActiveAction.isReady )
				{
					fMethodFound = mActiveAction.CanExecute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
					if(fMethodFound)
					{
						//trace("inv method found");
						mActiveAction.Execute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
					}
					else
					{
						//trace("inv method NOT found");
						mPlayerChar.Say(mActiveAction.GetNoActionText());
						mActiveAction = ActionsFactory.CreateAction(AdventureActions.ActionIdInteract);
						
					}
					
				}
				
				return ;
			}
			else // use item
			{
				if( mActiveAction.TestParameter(event.inventoryItem) )
				{
					mActiveAction.AddParameter( event.inventoryItem );
				}
				else // use item on itself
				{
					mPlayerChar.Say(mActiveAction.GetNoActionText());
					mModernGui.ReleaseItem();
					mActiveAction = ActionsFactory.CreateAction(AdventureActions.ActionIdInteract);
					return ;
				}
				
				if(mActiveAction.isReady)
				{
					//trace("use item ready");
					fMethodFound = mActiveAction.CanExecute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
					if(fMethodFound)
					{
						//trace("inv method found");
						mActiveAction.Execute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
					}
					else
					{
						//trace("inv method NOT found");
						mPlayerChar.Say(mActiveAction.GetNoActionText());
						mActiveAction = ActionsFactory.CreateAction(AdventureActions.ActionIdInteract);
						
					}
					mModernGui.ReleaseItem();
				}
				
			}
			
		}
		
		public function OnInventoryItemOver(event:GuiEvent):void
		{
			
			var fFeedbackText:String = "" ;
			if( !mModernGui.mouseInfoDescription )
			{
				fFeedbackText = event.inventoryItem.interactionName ;
			}
			else
			{
				fFeedbackText = event.inventoryItem.interactionName + "\n";
				fFeedbackText += event.inventoryItem.description ;	
			}
			mModernGui.SetMouseInfoText( fFeedbackText );
			
			mModernGui.SetInfoBoxText( event.inventoryItem.interactionName + "\n" + event.inventoryItem.description );
			
			mModernGui.ChangeMouseCursorTo( ModernGui.ItemMouseCursor );
		}
		
		public function OnInventoryItemOut(event:GuiEvent):void
		{
			if(mModernGui.currentMouseCursorId == ModernGui.ItemMouseCursor)
			{
				mModernGui.ChangeMouseCursorTo( mModernGui.prevMouseCursorId );
				mModernGui.SetMouseInfoText("");
				mModernGui.SetInfoBoxText(" ");
			}
		}
		
		/**
		 * @inheritDoc
		 */		
		public function EndOfAction():void
		{
			if(mModernGui.currentMouseCursorId == ModernGui.GrabingItemMouseCursor)
			{
				mModernGui.ReleaseItem() ;
			}
			else
			{
				mModernGui.ChangeMouseCursorTo( ModernGui.NormalMouseCursor );
			}
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdInteract );
		}
		
		
		
	}
}